/*
 * tasks.c - producer consumer tasks used by main.c
 * by Robert Buchanan/Jacob Eichers
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tasks.h"
#include <ctype.h>



static int max( int a, int b );
static int min( int a, int b );
static void writeBuf( int fdOut, char *buf, int buflen );


void munch1 (int fdIn, int fdOut)
{
	char signs[] = "=========";
	char space[] = "*";
	int buflen = 0, end;
	int start = 0, num;
	char buf[BUF_MAX];
	
	do 
	{
		/*read the input stream */
		buflen = read(fdIn, buf, BUF_MAX);

		if( buflen<0 )
		{
			perror( "Read buffer" );
			exit( -1 );
		}

		
		/* systematically turn each number into equal signs */
		start = 0;
		for (end = 0; end < buflen; end++)
		{
			if ( isdigit(buf[end]) )
			{
				/* write from start to end before writing equals signs*/
				writeBuf( fdOut, &(buf[start]), end-start );

				/* skip over buf[end]. It has the actual number character*/
				start = end+1;

				/* write the equals signs corresponding to buf[end]*/
				num = buf[end] - '0';
				writeBuf( fdOut, signs, num );

			} else if( buf[end]==' ' )
			{
				/* write from start to end before writing equals signs*/
				writeBuf( fdOut, &(buf[start]), end-start );
				
				/* skip over buf[end]. It has the actual space character*/
				start = end+1;

				/* write a space to the stream*/
				writeBuf(fdOut, space, 1);
			}
		}

		/* write the part of the buffer AFTER any numbers*/
		writeBuf( fdOut, &(buf[start]), end-start );

	} while (buflen != 0);

}

void munch2 (int fdIn, int fdOut)
{
	int buflen = 0, counter;
	char buf[BUF_MAX];
	
	do 
	{
		
		/*read the input stream */
		buflen = read(fdIn, buf, BUF_MAX);

		if( buflen<0 )
		{
			perror( "Read buffer" );
			exit( -1 );
		}

		/* systematically make each character lower case*/
		for (counter = 0; counter < buflen; counter++)
		{
			if (islower(buf[counter]))
				buf[counter] = toupper(buf[counter]);
		}
	
		writeBuf( fdOut, buf, buflen );

	} while (buflen != 0);
}

void reader( int fdIn, int fdOut )
{
	char buf[ BUF_MAX ];
	char *lineterm = "\0";
	int linelen, start, end, buflen;

	buflen = linelen = start = end = 0;

	do
	{
		/* rebuffer until full*/
		if( start>=buflen-1 )
		{
			buflen = read(fdIn, buf, BUF_MAX);

			if( buflen<0 )
			{
				perror( "Read buffer" );
				exit( -1 );
			}
			
			start = 0;
		}

		
		/* next area extends to end of buffer or till buf[end] will be a newline*/
		for( end=start+1; end<buflen && buf[end-1]!='\n'; end++ )
			{}
		
		/* write all within [start, end] AND [start, linelimit]*/
		writeBuf( fdOut, &(buf[start]), min(max(LINE_LIMIT-linelen, 0), end-start) );
		linelen += end-start;

		/* test if we found a new line, not just ran out of buffer*/
		if( buf[end-1]=='\n' )
		{
			linelen = 0;
			writeBuf( fdOut, lineterm, 1 );
		}


		/* next time, begin beyond upper bound*/
		start = end;

	} while( buflen!=0 );
}

void writer (int fdIn, int fdOut)
{
	char buf[BUF_MAX];
	int buflen;
	
	do
	{
		buflen = read( fdIn, buf, BUF_MAX );

		if( buflen<0 )
		{
			perror( "Read buffer" );
			exit( -1 );
		}

		writeBuf( fdOut, buf, buflen );

	} while( buflen>0 );
}

static void writeBuf( int fdOut, char *buf, int buflen )
{
	int n, t;

	n = 0;
	while( n<buflen )
	{
		t = write( fdOut, &(buf[n]), buflen-n );

		if( !t>0 )
		{
			perror( "Writing buffer" );
			exit( -1 );
		}

		n += t;
	}
}

static int max( int a, int b )
{
	return a>b ? a : b;
}


static int min( int a, int b )
{
	return a<b ? a : b;
}
